package com.practices.util;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;

import com.practices.bean.ProcessInfo;

import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Debug;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.view.WindowManager;

public class SystemInfoUtil {
	public static final String SYSTEM_NAME = "Android";
	private static final Pattern MTK_PATTERN = Pattern.compile("^[MT]{2}[a-zA-Z0-9]{0,10}$");

	private static int STATISTICS_PLATFORM_MTK = 1;
	private static int STATISTICS_PLATFORM_QUALCOMM = 2;

	public static int getPlatForm() {
		if (getHardware().equals("QCOM"))
			return STATISTICS_PLATFORM_QUALCOMM;
		if (MTK_PATTERN.matcher(getHardware()).find()) {
			return STATISTICS_PLATFORM_MTK;
		}
		return 0;
	}

	public static String getManufacture() {
		if (!isEmpty(Build.MANUFACTURER)) {
			if (Build.BRAND.toLowerCase().equals("oppo"))
				return Build.BRAND;
			if (!Build.MANUFACTURER.toLowerCase().equals("unknown")) {
				return Build.MANUFACTURER;
			}
			return "0";
		}

		return "0";
	}

	public static String getModel() {
		if (!isEmpty(Build.MODEL)) {
			return Build.MODEL;
		}
		return "0";
	}

	public static int getSDKVersion() {
		return Build.VERSION.SDK_INT;
	}

	public static String getRomVersion() {
		if (!isEmpty(Build.VERSION.RELEASE)) {
			return Build.VERSION.RELEASE;
		}
		LogUtil.w("my_practices", "No ROM VERSION.");
		return "0";
	}

	public static String getImei(Context context) {
		String imei = "0";
		try {
			TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService("phone");
			imei = telephonyManager.getDeviceId();
			if (isEmpty(imei))
				LogUtil.w("NearMeStatistics", "No IMEI.");
			return "0";
		} catch (Exception e) {
			LogUtil.e("my_practices", "Failed to take mac as IMEI.");
		}
		return imei;
	}

	public static String getHardware() {
		if (!isEmpty(Build.HARDWARE)) {
			return Build.HARDWARE.toUpperCase();
		}
		return "0";
	}

	public static String getResolution(Context context) {
		String screenSize = "0";
		try {
			DisplayMetrics dm = new DisplayMetrics();
			WindowManager manager = (WindowManager) context.getSystemService("window");
			manager.getDefaultDisplay().getMetrics(dm);
			screenSize = dm.heightPixels + "#" + dm.widthPixels;
		} catch (Exception e) {
			LogUtil.e("my_practices", "Failed to take resolution.");
		}
		return screenSize;
	}

	public static String getLanguage(Context context) {
		if (Locale.getDefault().getCountry().equals("CN"))
			return "zh-cn";
		if (Locale.getDefault().getCountry().equals("TW"))
			return "zh-tw";
		if (Locale.getDefault().getCountry().equals("US")) {
			return "en-us";
		}
		return "zh-cn";
	}

	public static String getCountry(Context context) {
		return Locale.getDefault().getCountry();
	}

	public static String getLocalPhoneNO(Context context) {
		try {
			TelephonyManager tm = (TelephonyManager) context.getSystemService("phone");
			if (!isEmpty(tm.getLine1Number())) {
				return tm.getLine1Number();
			}
			return "0";
		} catch (Exception e) {
			LogUtil.e("my_practices", e);
		}
		return "0";
	}

	public static String getOperators(Context context) {
		try {
			TelephonyManager tm = (TelephonyManager) context.getSystemService("phone");
			return tm.getNetworkOperatorName();
		} catch (Exception e) {
			LogUtil.e("my_practices", e);
		}
		return "";
	}

	public static String getMacAddress(Context context) {
		try {
			WifiManager wifi = (WifiManager) context.getSystemService("wifi");
			WifiInfo info = wifi.getConnectionInfo();

			if (!isEmpty(info.getMacAddress())) {
				return info.getMacAddress();
			}
			LogUtil.w("my_practices", "NO MAC ADDRESS.");
			return "0";
		} catch (Exception e) {
			LogUtil.e("my_practices", e);
		}
		return "0";
	}

	private static boolean isEmpty(String str) {
		if ((str == null) || ("null".equals(str)) || ("".equals(str))) {
			return true;
		}
		return false;
	}

	// 一、利用Android API函数查看
	// 1.1 ActivityManager查看可用内存。

	/*
	 * 1.2、android.os.Debug查询PSS，VSS，USS等单个进程使用内存信息 MemoryInfo[] memoryInfoArray
	 * = am.getProcessMemoryInfo(pids); MemoryInfo
	 * pidMemoryInfo=memoryInfoArray[0]; pidMemoryInfo.getTotalPrivateDirty();
	 * 
	 * getTotalPrivateDirty() Return total private dirty memory usage in kB. USS
	 * 
	 * getTotalPss() Return total PSS memory usage in kB. PSS
	 * getTotalSharedDirty() Return total shared dirty memory usage in kB. RSS
	 */

	public void getSystemInfo(Context cx) {
		long mem_unused;
		ActivityManager am = (ActivityManager) cx.getSystemService(Context.ACTIVITY_SERVICE);
		ActivityManager.MemoryInfo mi = new MemoryInfo();
		am.getMemoryInfo(mi);
		// 取得剩余的内存空间
		mem_unused = mi.availMem / 1024;

	}

	// 二、直接对Android文件进行解析查询，
	// /proc/cpuinfo系统CPU的类型等多种信息。
	// /proc/meminfo 系统内存使用信息
	// 获得总内存
	public static long getmem_TOLAL() {
		long mTotal;
		// /proc/meminfo读出的内核信息进行解释
		String path = "/proc/meminfo";
		String content = null;
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(path), 8);
			String line;
			if ((line = br.readLine()) != null) {
				content = line;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		// beginIndex
		int begin = content.indexOf(':');
		// endIndex
		int end = content.indexOf('k');
		// 截取字符串信息

		content = content.substring(begin + 1, end).trim();
		mTotal = Integer.parseInt(content);
		return mTotal;
	}

	// 三、通过Android系统提供的Runtime类，执行adb 命令(top,procrank,ps...等命令)查询
	// 通过对执行结果的标准控制台输出进行解析。这样大大的扩展了Android查询功能.例如：

	/*
	 * # procrank Runtime.getRuntime().exec("/system/xbin/procrank");
	 * 内存耗用：VSS/RSS/PSS/USS Terms • VSS - Virtual Set Size 虚拟耗用内存（包含共享库占用的内存） •
	 * RSS - Resident Set Size 实际使用物理内存（包含共享库占用的内存） • PSS - Proportional Set
	 * Size 实际使用的物理内存（比例分配共享库占用的内存） • USS - Unique Set Size
	 * 进程独自占用的物理内存（不包含共享库占用的内存） 一般来说内存占用大小有如下规律：VSS >= RSS >= PSS >= USS
	 */

	// final Process m_process =
	// Runtime.getRuntime().exec("/system/bin/top -n 1");
	// final StringBuilder sbread = new StringBuilder();
	// BufferedReader bufferedReader = new BufferedReader(new
	// InputStreamReader(m_process.getInputStream()), 8192);

	// For example, to run /system/bin/ping to ping android.com:

	public static void runCommand() throws IOException {
		Process process = new ProcessBuilder().command("/system/bin/ping", "android.com").redirectErrorStream(true).start();
		try {
			InputStream in = process.getInputStream();
			OutputStream out = process.getOutputStream();
			// readStream(in);
		} finally {
			process.destroy();
		}
	}
	/**
	 * kill进程
	 */
	private void killProcess(Context cx, String packageName) {
		ActivityManager am = (ActivityManager) cx.getSystemService(Context.ACTIVITY_SERVICE);
		am.killBackgroundProcesses(packageName);
	}

	// 获得系统进程信息
	public static  List<ProcessInfo> getRunningAppProcessInfo(Context cx) {
		// ProcessInfo Model类 用来保存所有进程信息
		List<ProcessInfo> processinfoList = new ArrayList<ProcessInfo>();

		ActivityManager mActivityManager = (ActivityManager) cx.getSystemService(cx.ACTIVITY_SERVICE);
		// 通过调用ActivityManager的getRunningAppProcesses()方法获得系统里所有正在运行的进程
		List<ActivityManager.RunningAppProcessInfo> appProcessList = mActivityManager.getRunningAppProcesses();

		for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessList) {
			// 进程ID号
			int pid = appProcessInfo.pid;
			// 用户ID 类似于Linux的权限不同，ID也就不同 比如 root等
			int uid = appProcessInfo.uid;
			// 进程名，默认是包名或者由属性android：process=""指定
			String processName = appProcessInfo.processName;
			// 获得该进程占用的内存
			int[] myMempid = new int[] { pid };
			// 此MemoryInfo位于android.os.Debug.MemoryInfo包中，用来统计进程的内存信息
			Debug.MemoryInfo[] memoryInfo = mActivityManager.getProcessMemoryInfo(myMempid);
			// 获取进程占内存用信息 kb单位
			// 转换成MB /1024
			int memSize = memoryInfo[0].dalvikPrivateDirty / 1024;

			LogUtil.e(LogUtil.LOG_TAG, "processName: " + processName + "  pid: " + pid + " uid:" + uid + " memorySize is -->" + memSize + "kb");

			// 构造一个ProcessInfo对象
			ProcessInfo processInfo = new ProcessInfo();
			processInfo.setPid(pid);
			processInfo.setUid(uid);
			processInfo.setMemSize(memSize);
			processInfo.setPocessName(processName);
			//
			processinfoList.add(processInfo);

			// 获得每个进程里运行的应用程序(包),即每个应用程序的包名
			String[] packageList = appProcessInfo.pkgList;
			LogUtil.e(LogUtil.LOG_TAG, "process id is " + pid + "has " + packageList.length);
			for (int i = 0; i < packageList.length; i++) {
				LogUtil.e(LogUtil.LOG_TAG, "packageName " + packageList[i] + " in process id is -->" + pid);
			}
		}
		return processinfoList;
	}

}
